package com.doordu.soa.service.web.fieldvalidator;

import com.doordu.soa.service.web.annotation.DataValid;
import org.apache.commons.lang.StringUtils;

import java.lang.reflect.Field;
import java.util.List;

/**
 * Created by zjp on 2017/4/19.
 */
interface BaseValidatorHandler<T> {
    String PASS = null;
    static DestFieldValue getFieldAndValue(String fieldName, Object bean) {
        try {
            Field field = bean.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            DataValid dataValid = field.getAnnotation(DataValid.class);
            return new DestFieldValue(field.get(bean), dataValid.description());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    default String validate(DataValid dataValid, Object bean, T value) {
        if (dataValid.nullable() && value == null) {
            return PASS;
        }
        String errMsg = PASS;
        boolean eqExp = StringUtils.isNotEmpty(dataValid.eq());
        boolean neExp = StringUtils.isNotEmpty(dataValid.noteq());
        boolean gtExp = StringUtils.isNotEmpty(dataValid.gt());
        boolean ltExp = StringUtils.isNotEmpty(dataValid.lt());

        boolean needCompare = eqExp || neExp || gtExp || ltExp;

        if (needCompare) {
            errMsg = doCompare(dataValid, bean, (Comparable<T>) value);
            if (StringUtils.isNotEmpty(errMsg)) {
                return errMsg;
            }
        }
        if (List.class.isAssignableFrom(value.getClass())) {
            return doValidate(dataValid, bean, (List<T>) value);
        } else {
            return doValidate(dataValid, bean, value);
        }
    }

    default String doCompare(DataValid dataValid, Object bean, Comparable<T> src) {
        String gtField = dataValid.gt();
        String ltField = dataValid.lt();
        String notEqField = dataValid.noteq();
        String eqField = dataValid.eq();
        if (StringUtils.isNotEmpty(gtField)) {
            DestFieldValue destFieldValue = getFieldAndValue(gtField, bean);
            if (src.compareTo((T) destFieldValue.getValue()) <= 0) {
                return String.format(" 必须大于 %s 的值", destFieldValue.getDesc());
            }
        }

        if (StringUtils.isNotEmpty(ltField)) {
            DestFieldValue destFieldValue = getFieldAndValue(ltField, bean);
            if (src.compareTo((T) destFieldValue.getValue()) >= 0) {
                return String.format(" 必须小于 %s 的值", destFieldValue.getDesc());
            }
        }

        if (StringUtils.isNotEmpty(notEqField)) {
            DestFieldValue destFieldValue = getFieldAndValue(notEqField, bean);
            if (src.compareTo((T) destFieldValue.getValue()) == 0) {
                return String.format(" 不能等于 %s 的值", destFieldValue.getDesc());
            }
        }
        if (StringUtils.isNotEmpty(eqField)) {
            DestFieldValue destFieldValue = getFieldAndValue(eqField, bean);
            if (src.compareTo((T) destFieldValue.getValue()) != 0) {
                return String.format("必须等于 %s", destFieldValue.getDesc());
            }
        }
        return null;
    }

    default String doValidate(DataValid dataValid, Object field, T value) {
        return null;
    }

    default String doValidate(DataValid dataValid, Object field, List<T> value) {
        return null;
    }

    class DestFieldValue {
        Object value;
        String desc;

        public DestFieldValue(Object value, String desc) {
            this.value = value;
            this.desc = desc;
        }

        public Object getValue() {
            return value;
        }

        public void setValue(Object value) {
            this.value = value;
        }

        public String getDesc() {
            return desc;
        }

        public void setDesc(String desc) {
            this.desc = desc;
        }
    }

}
